package chinaums.common.listener;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.WebApplicationContextUtils;

import chinaums.common.util.CfpsRecvMQAppModel;
import chinaums.service.impl.CfpsMQFactoryRcvQueueImpl;
import chinaums.service.impl.MessageListenerImpl;
/**
 * 
 * @author liyongjie
 * @time 2017年7月19日 下午1:15:43
 * @version v1.0
 * @description 编写监听实现ServletContextListener,通过实现来实现监听MQ流水值，通过编写线程用run()方法实现当项目启动的时候开启监听
 */


@Component
public class MyListener implements ServletContextListener{
	/*
	 * 1，实例化线程myThread与MessageListenerImpl
	 * 2,编写实现ServletContextListener的方法当项目启动时在contextInitialized()方法里面添加通过线程写的监听方法启动线程开启监听，
	 * 当项目关闭的时候在contextDestroyed()方法里面中断线程关闭监听。
	 */
	private MyThread myThread;   
	 MessageListenerImpl mess;
	//启动项目时，开启监听
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		//定义当str等于空与Mythread等于空的时候实例化监听开启监听
		String str = null;  
        if (str == null && myThread == null) {  
            myThread = new MyThread(sce);
         // servlet 上下文初始化时启动 socket ，线程开启，监听启动。
            myThread.start(); 
        }  
       
	}
	//关闭项目时，中断监听
	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		//当线程不等与空的时候与中断状态清除的时候，中断线程
		  if (myThread != null && myThread.isInterrupted()) {  
	            myThread.interrupt();  
	        }  
	}
}
/*
 * 编写线程类继承Thread类，把监听的内容通过run()方法来启动。
 */
@Component
class MyThread extends Thread { 
	
private final static Logger log = LoggerFactory.getLogger(MyThread.class);
	//MQ所在IP	
	public static String hostName;
	//MQ监听所在端口
	public static int port;
	//获取消息的MQ队列管理器
	public static String queueManager;
	//获取消息的MQ通道
	public static String channel;
	//获取消息的队列名称
	public static String queueName;
	//项目名称
	public static String projectName;
	//模块名称
	public static String moduleName;
	//监听重启次数
	public static int lisRestartTimes;
	//监听重启间隔时间
	public static int lisPauseTime;
	//监控异常间隔时间
	public static int moniPauseTime;
	private ServletContextEvent sce;
	
	
	/**
	 * @return the sce
	 */
	public ServletContextEvent getSce() {
		return sce;
	}
	/**
	 * @param sce the sce to set
	 */
	public void setSce(ServletContextEvent sce) {
		this.sce = sce;
	}


	//配置初始化
	static {
		Properties prop = new Properties();   
        InputStream in = MyThread.class.
        		getClassLoader().getResourceAsStream("app.properties");
        
        try {   
            prop.load(in); 
            MyThread.hostName = prop.getProperty("rcvHost").trim();
            MyThread.port = Integer.parseInt(prop.getProperty("rcvPort").trim());
            MyThread.queueManager = prop.getProperty("rcvQueueManager").trim();
            MyThread.channel = prop.getProperty("rcvChannel").trim();
            MyThread.queueName = prop.getProperty("rcvQueueName").trim();
            MyThread.projectName = prop.getProperty("rcvProjectName").trim();
            MyThread.moduleName = prop.getProperty("rcvModuleName").trim();
    		MyThread.lisRestartTimes = Integer.parseInt(prop.getProperty("lisRestartTimes").trim());
    		MyThread.lisPauseTime = Integer.parseInt(prop.getProperty("lisPauseTime").trim());
    		MyThread.moniPauseTime = Integer.parseInt(prop.getProperty("moniPauseTime").trim());
        } catch (IOException e) {   
            e.printStackTrace();   
        } finally {
        	if(in != null) {
        		try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
        	}
        }
	}
	
	public MyThread() {
	};

	public MyThread(ServletContextEvent sce) {
		this.sce = sce;
	};
	
	
	 public void run() {  
	        while (!this.isInterrupted()) {// 线程未中断执行循环  
	            // Thread.sleep(1000); //每隔1000ms执行一次  
	                int currentTimes = 0;
	                //实例化  MessageListenerImpl的bean
	                MessageListenerImpl listener = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean(MessageListenerImpl.class);
	        		CfpsMQFactoryRcvQueueImpl mqFactory = new CfpsMQFactoryRcvQueueImpl(
	        				hostName, port, queueManager, channel, queueName, projectName,
	        				moduleName);
	        		CfpsRecvMQAppModel appModel = new CfpsRecvMQAppModel("App");
	        		// 设置工厂
	        		appModel.setFactory(mqFactory);
	        		// 设置消息监听器
	        		appModel.setMqMessageListener(listener);
	        		// 初始化
	        		appModel.init();
	        		//对于监听通过以下判断来开启监听
	        		while (true) {
	        			if (!listener.isOk()) {
	        				// 停止监听
	        				appModel.stop();
	        				if (currentTimes > lisRestartTimes) {
	        					break;
	        				}
	        				try {
	        					Thread.sleep(lisPauseTime);
	        				} catch (InterruptedException e) {
	        					log.error("" + e);
	        				}
	        				// 启动监听
	        				appModel.start();
	        				log.info("监听已启动");
	        				currentTimes++;
	        			}
	        			try {
	        				Thread.sleep(moniPauseTime);
	        			} catch (InterruptedException e) {
	        				log.error("" + e);
	        			}
	        		}  
//	           ------------------ 开始执行 ---------------------------  
	           // System.out.println("____FUCK TIME:" + System.currentTimeMillis());  
	        }  
	    } 
	
}
